<!DOCTYPE html>
<html lang="en">
  <!-- https://www.cnblogs.com/ruizer/p/14134162.html -->
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script src="./mock.js"></script>
    <style>
      .a-center {
        text-align: center;
      }

      .a-right {
        text-align: right;
      }

      table,
      thead,
      tbody,
      td,
      th {
        border: 1px solid #ddd;
        border-collapse: collapse;
      }
      thead {
        position: -webkit-sticky;
        position: sticky;
        top: 0;
        border: 1px solid #ddd;
        z-index: 1;
      }
      th {
        background-color: #f7f7f7;
      }
      a {
        cursor: pointer;
        color: blue;
      }

      a.link {
        margin: 0 2px;
      }
      a.drag {
        cursor: move;
      }
      tr {
        height: 45px;
      }
      #app {
        width: 100%;
      }
      .body {
        position: relative;
        height: 600px;
        overflow: auto;
      }
    </style>
  </head>

  <body>
    <div id="app">
      <div id="tools">
        
      <button onclick="addRow(1)">添加行</button>
      <button onclick="addCol(0)">添加列</button>
      <button id="ones">ones</button>
      </div>
      <div class="body">
        <table id="table">
          <thead></thead>
          <tbody></tbody>
        </table>
      </div>
    </div>

    <script type="module">
      /*
  1. 数据绑定
  2. 表格绘制。
  3. 添加行
  4. 添加列/删除列
  5. 显示/隐藏列
  6. 列宽调整
  8. 树形数据
  9. 展开/收缩树
  10. 拖拽行
  */
      import { h, patch,Qinput } from './h.js'
      let state = {
        columns: [
          { type: "seq", width: 70, title: "Seq" },
          { type: "drag", width: 70, title: "drag" },
          { type: "operate", width: 260, title: "operate" },
          { field: "id", title: "Id" },
          { field: "name", title: "Name", width: 2000, edit: true },
          { field: "sex", type: "input", title: "Sex" },
          { field: "age", title: "Age" },
        ],
      };
      let list = Mock.mock({
        "data|20": [
          {
            "id|+1": 1,
            name: "@cname",
            "sex|1": ["男", "女"],
            "age|1-100": 1,
            address: "@city(true)",
          },
        ],
      });
      console.warn("list", list);
      let component = {
        data: null,
        render: null,
      };
      // const observer = new MutationObserver((mut) => {
      //   console.warn(mut);
      // });
      // observer.observe(table, {
      //   childList: true,
      //   subtree: true,
      //   attributes: true,
      //   characterData: true,
      // });
      let dom = {
        init(columns) {
          const thead = table.querySelector("thead");
          let ths = [];
          let cols = [];
          let colTh = {
            target: null,
            x: 0,
            w: 0,
          }; // 拖拽的列
          columns.forEach((c, i) => {
            let th = h(
              "th",
              {
                onMousedown: (e) => {
                  if (!(e && e.target)) return;
                  const vm = e.target;
                  // 更改鼠标样式
                  if (e.offsetX > vm.offsetWidth - 10) {
                    colTh.target = e.target;
                    colTh.x = e.x;
                    colTh.w = vm.offsetWidth;
                  }
                },
                onMousemove: (e) => {
                  if (!(e && e.target)) return;
                  const vm = e.target;
                  // 更改鼠标样式
                  if (e.offsetX > vm.offsetWidth - 10) {
                    vm.style.cursor = "col-resize";
                  } else {
                    vm.style.cursor = "default";
                  }
                  if (colTh.target !== null && colTh.target === vm) {
                    console.warn("move", e, colTh, vm);
                    let name = vm.getAttribute("name");
                    let width = colTh.w - colTh.x + e.clientX;
                    table.querySelector(`col[name="${name}"]`).style.width =
                      width + "px";
                  }
                },
                onMouseUp: (e) => {
                  colTh = { target: null, x: 0, w: 0 };
                },
                name: `c${i}`,
              },
              c.title
            );
            ths.push(th);
            let style = "";
            if (c.width) {
              style = ` style="width: ${c.width}px;"`;
            } else {
              style = ` style="width: 800px;"`;
            }
            let col = `<col name="c${i}"${style}>`;
            cols.push(col);
          });
          table.insertBefore(h("colgroup", {}, cols.join("")), thead);
          thead.insertBefore(h("tr", {}, ths), null);
        },
        rowOperate(target, code) {},
        bind(data, columns) {
          const { rowOperate, renderTr } = dom;
          const tbody = table.querySelector("tbody");
          const trs = [];
          let drag = null;
          data.forEach((d, j) => {
            tbody.append(renderTr(columns, d, j));
          });
        },
        renderBody(columns, rows, parent = null) {},
        renderTr(columns, row, j, parent = null) {
          let { renderTr, renderTd } = dom;
          let d = row;
          let tr = h("tr", {
            rid: d.id,
            draggable: true,
            onDragstart: (e) => {
              const data = e.dataTransfer;
              drag = e.target;
            },
            onDragover: (e) => e.preventDefault(),
            onDrop: (e) => {
              // tbody.insertBefore(drag, e.target.parentNode);
              e.target.parentNode.before(drag);
              e.preventDefault();
            },
          });
          let tds = columns.map((c, i) => renderTd(c, d, j, tr));
          tr.append(...tds);
          return tr;
        },
        renderTd(column, row, rowIndex, parent = null) {
          let d = row;
          let c = column;
          let th = parent;
          let j = rowIndex;
          let td;
          let value = d[c.field];
          if (c.type == "seq") {
            value = j + 1;
          } else if (c.type == "drag") {
            value = `<a class="drag">X</a>`;
          } else if (c.type == "input") {
            // value = h(Qinput, {
            //   vmodel: value,
            //   "@setValue": (v) => {
            //     d[c.field] = v;
            //   },
            // });
          } else if (c.type == "operate") {
            let a = h(
              "a",
              {
                className: "link",
                onClick: (e) => {
                  rowOperate(th, d);
                },
              },
              "^"
            );
            let b = h(
              "a",
              {
                className: "link",
                onClick: (e) => {
                  rowOperate(th, d);
                },
              },
              "+"
            );
            let c = h(
              "a",
              {
                className: "link",
                onClick: (e) => {
                  rowOperate(e.target);
                },
              },
              "x"
            );
            value = [a, b, c];
          }
          let props = {
            className: "a-center",
          };
         /*  if (column.edit) {
            props["onClick.once"] = (e) => {
              // e.stopPropagation();
              if (!td._edit) {
                td.innerHTML = "";
                let input = h(Qinput, {
                  vmodel: c.field,
                  "@setValue": (v) => {
                    d[c.field] = v;
                    console.warn("dataList", d);
                  }
                },row);
                // td.append(input);
                // input.focus();
                if (input.setSelectionRange) {
                  var len = value.length;
                  input.setSelectionRange(len, len);
                }
                td._edit = true;
              }
            };
            // props.onOut=(e)=>{
            //     // console.warn("onOut",e);
            //     td._edit =false;
            //     td.innerHTML=d[c.field];
            // }
          } */
          td = h("td", props, value);
          return td;
        },
      };
      let operate = {
        reload() {},
        insert() {},
        insertAt() {},
        get() {},
        remove() {},
        update() {},
        addColumn() {},
        removeColumn() {},
        hideColumn() {},
        showColumn() {},
      };
      dom.init(state.columns);
      dom.bind(list.data, state.columns);
    </script>
  </body>
</html>
